//
// Created by casdon on 2024/9/10.
//

#ifndef CIOT_CSDK_NET_H
#define CIOT_CSDK_NET_H

#include "types.h"

#ifdef __cplusplus
extern "C" {
#endif

#define CLINK_AP_IP "192.168.5.1"
//#define CLINK_AP_IP "192.168.43.1"
// #define CLINK_AP_IP "172.16.240.216"
#define CLINK_AP_NETMASK "255.255.255.0"
#define LIMITED_BROADCAST_ADDRESS "255.255.255.255"
#define CLINK_AP_TCP_PORT 12345
#define CLINK_AP_UDP_PORT 12345
typedef struct ciot_net_adapter_manager_s
{
    bool inited;

    CIOT_PRIVATE    int (*clink_broadcast_start) ();

    CIOT_ADAPTER    Ciot_res (* init)(void);
    CIOT_ADAPTER    Ciot_res (* deinit)(void);

    CIOT_ADAPTER    Ciot_res (*get_ip_address)( uint32_t * ip );
    CIOT_ADAPTER    uint16_t (*htons)(uint16_t n);
    CIOT_ADAPTER    uint16_t (*ntohs)(uint16_t n);
    CIOT_ADAPTER    uint32_t (*inet_addr)( const char *strip);

    /**
     * Socket communication
     */
    CIOT_ADAPTER    void (*fd_set_init)(void);
    CIOT_ADAPTER    void (*fd_zero)(void);
    CIOT_ADAPTER    void (*fd_set)( int fd );
    CIOT_ADAPTER    int  (*fd_is_set)( int fd );
    CIOT_ADAPTER    int  (*select)(int maxfd_plus1, Ciot_time_ms timeout_ms);
    CIOT_ADAPTER    int  (*accept)(int s, char* strip, unsigned short rip_len);

    CIOT_ADAPTER    int  (*set_receive_timeout)(int s, Ciot_time_ms ms);
    CIOT_ADAPTER    int  (*set_send_timeout)(int s, Ciot_time_ms ms);

    CIOT_ADAPTER    int  (*tcp_server_init)( uint32_t ip, uint16_t port, Ciot_duration_ms timeout );
    CIOT_EVENT      int  (*tcp_read)( uint8_t* buffer, int len, Ciot_duration_ms timeout );
    CIOT_ADAPTER    int  (*tcp_write)( uint8_t* buffer, int len, Ciot_duration_ms timeout );

    CIOT_ADAPTER    int  (*udp_init)( uint8_t*  ip, uint16_t port, Ciot_duration_ms timeout, bool broadcast );
    CIOT_EVENT      int  (*udp_read)(int fd, uint8_t* buf, uint16_t len, char* rip, uint16_t rip_len, uint16_t port);
    CIOT_ADAPTER    int  (*udp_write)(int fd, const uint8_t* buf, uint16_t len, const char* rip, uint16_t port);

    CIOT_ADAPTER    int  (*open)(int *socket_fd, int port, char* addr, int *p_server_ip);
    CIOT_ADAPTER    int  (*close)( int fd );


    CIOT_ADAPTER    Ciot_res (* set_dns) (uint64_t server);

} ciot_net_adapter_manager;

extern Ciot_res ciot_porting_net_init();

#if CIOT_SDK_FOR_LINUX
ciot_net_adapter_manager * ciot_net_adapter_posix();
#endif

CIOT_API
Ciot_res ciot_net_adapter_manager_reg( ciot_net_adapter_manager * network_adapter );

CIOT_API
const ciot_net_adapter_manager * ciot_net_adapter_manager_instance();

#define ciot_net_reg(A) ciot_net_adapter_manager_reg(A)
#define ciot_net_mgr() ciot_net_adapter_manager_instance()
#define ciot_net() ciot_net_mgr()


#ifdef __cplusplus
}
#endif

#endif //CIOT_CSDK_NET_H
